import * as THREE from 'three';
import M from 'scripts/main.js';
import { TWEEN } from 'three/addons/libs/tween.module.min.js';
import { TrackballControls } from 'three/addons/controls/TrackballControls.js';
import { CSS3DRenderer, CSS3DObject } from 'three/addons/renderers/CSS3DRenderer.js';
import {City} from 'scripts/city.js';
import {GameList} from 'scripts/gameList.js';

class Square {
	constructor(books){	
		let animationID;
		let objects = [];

		let camera, scene, renderer, controls;
		const m = new M();

		init();

		function init() {
			if(!books) books = m.loadJson("books");
			let targets = [];
			
			THREE.Cache.enabled = true;
			m.display("goback",true);
			m.getNode("goback").addEventListener('pointerdown', goback);
			window.addEventListener( 'resize', onWindowResize );

			camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1000, 10000 );
			camera.position.z = 1500;
			scene = new THREE.Scene();
			
			for ( let i = 0; i < books.length; i ++ ) {
				var book = books[i];
				if (!book.progress) book.progress=0;
				const element = document.createElement( 'div' );
				element.className = 'element';
				element.id=i;
				element.style.backgroundColor = 'rgba(0,127,127,' + m.getTransparency(book.rare) + ')';
				//这里是关键，不可以用click，估计是为了同时兼顾手机
				element.addEventListener('pointerdown', open);

				const number = document.createElement( 'div' );
				number.className = 'number';
				number.textContent = m.getBookNo(book.id);
				element.appendChild( number );

				const symbol = document.createElement( 'div' );
				symbol.className = 'symbol';
				symbol.textContent = book.zis[0].zi;
				element.appendChild( symbol );
				let sum=0;
				for(let j=1;j<=16;j++){
					if (book["game"+j]) sum+=book["game"+j];
				}
				const details = document.createElement( 'div' );
				details.className = 'details';
				details.innerHTML = m.getRare(book.rare)+"<br>"+(sum/160).toFixed(2)+"%";
				element.appendChild( details );

				const objectCSS = new CSS3DObject( element );
				//必须将网页对象和3d对象关联起来，才能对其进行操作
				element.parent = objectCSS;
				objectCSS.position.x = Math.random() * 4000 - 2000;
				objectCSS.position.y = Math.random() * 4000 - 2000;
				objectCSS.position.z = Math.random() * 4000 - 5000;
				objectCSS.rotation.x = Math.random();
				objectCSS.rotation.y = Math.random();
				objectCSS.rotation.z = Math.random();
				scene.add( objectCSS );

				objects.push( objectCSS );
				//图片旋转的弧度值，超过40个就均匀的排成一圈，否则大约每9度放一个。
				const theta = books.length >40 ? i * (2*Math.PI/books.length): i*0.17;
				const object = new THREE.Object3D();
				object.position.setFromCylindricalCoords( 900, theta, 0 );
				//指向圆心的向量
				const vector = new THREE.Vector3();
				vector.x = object.position.x * 2;
				vector.y = 0;
				vector.z = object.position.z * 2;

				//使图片指向圆心
				object.lookAt( vector );
				targets.push( object );
			}

			renderer = new CSS3DRenderer();
			renderer.setSize( window.innerWidth, window.innerHeight );
			document.getElementById( 'container' ).appendChild( renderer.domElement );

			//

			controls = new TrackballControls( camera, renderer.domElement );
			controls.minDistance = 400;
			controls.maxDistance = 6000;
			controls.noPan = true;
			controls.addEventListener( 'change', render );
			
			transform(objects,targets, 1000 );
			animate();
		}
		function open() {
			let id = this.id;
			let tags = [],objs = [];
			for ( let i = 0; i < books.length; i ++ ) {
				var tag = new THREE.Object3D();
				objs.push(objects[i]);
				tag.position.x = Math.random() * 4000 - 2000;
				tag.position.y = Math.random() * 4000 - 2000;
				tag.position.z = 6100;
				tag.rotation.x = 0;
				tag.rotation.y = 0;
				tag.rotation.z = 0;
				tags.push( tag );
			}
			
			transform(objs,tags, 500 );

			setTimeout(()=>{
				destroy();
				new GameList(books[id]);
			},500);
			
		};
		
		function goback(){
			destroy();
			new City();
		}
		
		function transform(objects,targets, duration ) {

			TWEEN.removeAll();

			for ( let i = 0; i < objects.length; i ++ ) {

				const object = objects[ i ];
				const target = targets[ i ];

				new TWEEN.Tween( object.position )
					.to( { x: target.position.x, y: target.position.y, z: target.position.z }, duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

				new TWEEN.Tween( object.rotation )
					.to( { x: target.rotation.x, y: target.rotation.y, z: target.rotation.z }, duration )
					.easing( TWEEN.Easing.Exponential.InOut )
					.start();

			}

			new TWEEN.Tween( this )
				.to( {}, duration )
				.onUpdate( render )
				.start();

		}

		function onWindowResize() {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

			render();

		}

		function animate() {

			animationID = requestAnimationFrame( animate );

			TWEEN.update();

			controls.update();

		}

		function render() {

			renderer.render( scene, camera );

		}

		function destroy(){
			cancelAnimationFrame(animationID)
			TWEEN.removeAll();
			scene.clear();
			controls.dispose (); 
			renderer.content = null;

			m.getNode("goback").removeEventListener('pointerdown', goback);
			window.removeEventListener( 'resize', onWindowResize );
			m.getNode("container").removeChild(renderer.domElement);
			scene = null;
			camera = null;
			controls = null;
			renderer = null;
			objects = null;
		}			
	}
}
export { Square };